package web.mb;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;

import com.sun.jndi.url.dns.dnsURLContext;

import metier.entities.Client;
import metier.entities.Declaration;
import metier.entities.Employe;
import metier.entities.Message;
import metier.entities.Offre;
import metier.sess.IDeclarationLocal;
import metier.sess.IMessageLocal;
import metier.sess.IOffreLocal;
import metier.sess.IUtilisateurLocal;


@ManagedBean
@RequestScoped
public class BidMB {
	
	@EJB
	private IOffreLocal metier;
	
	@EJB
	private IDeclarationLocal metierDec;
	
	@EJB
	private IUtilisateurLocal metierClient;
	
	@EJB
	private IMessageLocal metierMessage;
	
	
	private String testbid="";
	
	private double price;
	private Integer minbid=new Integer(6);
	private Integer IdOffre;
	private Integer IdCarrier;
	private Integer minutes=6;
	private Integer TVA=6;
	private boolean bid;
	private Offre offre;
	static private Integer IdClient=new Integer(0);
	
	
	
	
	//Espace éxpediteur
	private List<Message> listeMessagesExpediteur=new ArrayList<Message>();
	private List<Offre> listeOffre=new ArrayList<Offre>();
	//liste des declaration non encore accepté ou declined
	private List<Declaration> listeDeclarations=new ArrayList<Declaration>();
	//liste des declarations accepté
	private List<Declaration> listeDeclarationsAccept=new ArrayList<Declaration>();
	//liste des declarations decliné
   private List<Declaration> listeDeclarationsdecline=new ArrayList<Declaration>();
   
 //Espace Transporteur
 	private List<Message> listeMessagesTransporteur=new ArrayList<Message>();
 	
 	//liste des declaration non encore accepté ou declined
 	private List<Declaration> listeDeclarationsTr=new ArrayList<Declaration>();
 	//liste des declarations accepté
 	private List<Declaration> listeDeclarationsAcceptTr=new ArrayList<Declaration>();
 	//liste des declarations decliné
    private List<Declaration> listeDeclarationsdeclineTr=new ArrayList<Declaration>();
	

    
    
	public Integer getIdClient() {
		return IdClient;
	}

	public void setIdClient(Integer idClient) {
		IdClient = idClient;
	}

	public List<Message> getListeMessagesExpediteur() {
		return listeMessagesExpediteur;
	}

	public void setListeMessagesExpediteur(List<Message> listeMessagesExpediteur) {
		this.listeMessagesExpediteur = listeMessagesExpediteur;
	}

	public List<Offre> getListeOffre() {
		return listeOffre;
	}

	public void setListeOffre(List<Offre> listeOffre) {
		this.listeOffre = listeOffre;
	}

	public List<Declaration> getListeDeclarations() {
		return listeDeclarations;
	}

	public void setListeDeclarations(List<Declaration> listeDeclarations) {
		this.listeDeclarations = listeDeclarations;
	}

	public List<Declaration> getListeDeclarationsAccept() {
		return listeDeclarationsAccept;
	}

	public void setListeDeclarationsAccept(List<Declaration> listeDeclarationsAccept) {
		this.listeDeclarationsAccept = listeDeclarationsAccept;
	}

	public List<Declaration> getListeDeclarationsdecline() {
		return listeDeclarationsdecline;
	}

	public void setListeDeclarationsdecline(
			List<Declaration> listeDeclarationsdecline) {
		this.listeDeclarationsdecline = listeDeclarationsdecline;
	}

	public List<Message> getListeMessagesTransporteur() {
		return listeMessagesTransporteur;
	}

	public void setListeMessagesTransporteur(List<Message> listeMessagesTransporteur) {
		this.listeMessagesTransporteur = listeMessagesTransporteur;
	}

	public List<Declaration> getListeDeclarationsTr() {
		return listeDeclarationsTr;
	}

	public void setListeDeclarationsTr(List<Declaration> listeDeclarationsTr) {
		this.listeDeclarationsTr = listeDeclarationsTr;
	}

	public List<Declaration> getListeDeclarationsAcceptTr() {
		return listeDeclarationsAcceptTr;
	}

	public void setListeDeclarationsAcceptTr(
			List<Declaration> listeDeclarationsAcceptTr) {
		this.listeDeclarationsAcceptTr = listeDeclarationsAcceptTr;
	}

	public List<Declaration> getListeDeclarationsdeclineTr() {
		return listeDeclarationsdeclineTr;
	}

	public void setListeDeclarationsdeclineTr(
			List<Declaration> listeDeclarationsdeclineTr) {
		this.listeDeclarationsdeclineTr = listeDeclarationsdeclineTr;
	}

	public boolean isBid() {
		return bid;
	}

	public void setBid(boolean bid) {
		this.bid = bid;
	}

	public double getPrice() {
		return price;
	}

	public void setPrice(double price) {
		this.price = price;
	}

	public Integer getMinbid() {
		return minbid;
	}

	public void setMinbid(Integer minbid) {
		this.minbid = minbid;
	}

	public Integer getIdCarrier() {
		return IdCarrier;
	}

	public void setIdCarrier(Integer idCarrier) {
		IdCarrier = idCarrier;
	}

	public Integer getTVA() {
		return TVA;
	}

	public void setTVA(Integer tVA) {
		TVA = tVA;
	}

	public Offre getOffre() {
		return offre;
	}

	public void setOffre(Offre offre) {
		this.offre = offre;
	}

	public Integer getIdOffre() {
		return IdOffre;
	}

	public void setIdOffre(Integer idOffre) {
		IdOffre = idOffre;
	}

	public String getTestbid() {
		return testbid;
	}

	public void setTestbid(String testbid) {
		this.testbid = testbid;
	}
	
	public List<Offre> listeOffre()
	{
		//récupérer les offres qui n sont pas expirée
		
		return metier.listeOffre(1,null,1);
		
	}
	
	
	
	public boolean TestBidboolean()
	{
		//récupérer l'offre selon l'id
		 offre=metier.getOffre(IdOffre);
		boolean a=true;
		//tester si l'offre est expiré
		if(offre.getDate_Expiration().compareTo(new Date())<=0)
		{
			a= false;
		}
		else
		{
		//si l'offre est archivé
	  if(offre.getStatutOffre()==6)
	  {
		  a=false;
		 
	  }
	  else
	  {
		  //tester si l'offre possède une déclaration accepté
		  int i;
		  List<Declaration> listeDeclaration=offre.getListeDeclaration();
		  for( i=0;i<listeDeclaration.size();i++)
		  {
			  if(listeDeclaration.get(i).getStatut()==2)
			  {
				 a=false;
				
			  }
		  }
		
		
		  //teser la dernière déclaration pour savoir si l'offre doit etre archivé ou pas
		  if(metierDec.getDeclarationGagnante(offre).size()!=0)
		  {
			
			  Date DQMP=metierDec.getDeclarationGagnante(offre).get(0).getDateCreation();
			  Date date = new Date();
			    
			    Calendar cal = Calendar.getInstance();
			    Calendar cal1 = Calendar.getInstance();
			    
			    cal1.setTime(date);
			    cal.setTime(DQMP);
			    
			    cal.add(Calendar.MINUTE, minutes);
			    //régler le probleme de l'heur
			  cal1.add(Calendar.HOUR, 1);
			  if(cal.getTime().compareTo(cal1.getTime())<=0)
			  {
				  Declaration d=metierDec.getDeclarationGagnante(offre).get(0);
				 //envoyer un message à l'expéditeur pour accepter
				  metierDec.updateDeclaration(d);
				  a=false;
			  }
			 
		  }
		  
	  }
		}
		return a;
	  

	}
	
	
	public String TestBid()
	{
		//récupérer l'offre selon l'id
		Offre offre=metier.getOffre(IdOffre);
		
		//tester si l'offre est expiré
		if(offre.getDate_Expiration().compareTo(new Date())<=0)
		{
			testbid=" you can't bid date expiration";
			bid=false;
		}
		else
		{
		//si l'offre est archivé
	  if(offre.getStatutOffre()==6)
	  {
		  testbid="can't bid archivé";
		  bid=false;
	  }
	  else
	  {
		  //tester si l'offre possède une déclaration accepté
		  int i;
		  List<Declaration> listeDeclaration=offre.getListeDeclaration();
		  for( i=0;i<listeDeclaration.size();i++)
		  {  
			 
			  if(listeDeclaration.get(i).getStatut()==2)
			  {
				
				  testbid="you can't bid declaration accepté";
				  bid=false;
				  break;
				  
			  }
			  
		  }
		 if(i>=listeDeclaration.size())
		 {
			 
		
			 testbid="you can bid aucune déclaration accepé";
			 bid=true;
			 
		 }
			 List<Declaration> ld=metierDec.getDeclarationGagnante(offre);
		  //teser la dernière déclaration pour savoir si l'offre doit etre archivé ou pas
		  if(ld.size()!=0)
		  {
			  
			  if(ld.get(0).getPrice() <= offre.getPrix_desire())
			  {
			 
			  Date DQMP=ld.get(0).getDateCreation();
			  
			  Date date = new Date();
			  
			  Calendar cal = Calendar.getInstance();
			  Calendar cal1 = Calendar.getInstance();
			    
			  cal1.setTime(date);
			  cal.setTime(DQMP);
			    
			  cal.add(Calendar.MINUTE, minutes);
			  
			    //régler le probleme de l'heur
			//  cal1.add(Calendar.HOUR, 1);
			  if(cal.getTime().compareTo(cal1.getTime())<=0)
			  {
				  
				
				  testbid="you can't bid extension";
				  //ajouter la declaration gagnante
				  Offre o=ld.get(0).getOffre();
				  o.setDecGanante(ld.get(0));
				  metier.updateOffre(o);
				 
				  bid=false;
			  }
			  else
			  {
				  testbid="you can bid extension"; 
				  bid=true;
				  price=ld.get(0).getPrice()-minbid;
			  }
			  }
			  
		  }
		  
	  }
		}
	  
		return "ici";
	}
	
	//programme qui archive les offres
	public String archive()
	{
		List<Offre> listeOffre=metier.listeOffre(1,null,0) ;
		System.out.println("archive"+listeOffre.size());
		for(int i=0;i<listeOffre.size();i++)
		{
			
			if((listeOffre.get(i).getDecGanante()==null) && (listeOffre.get(i).getDate_Expiration().compareTo(new Date()) < 0) )
			{
				
				System.out.println("lool");
				Offre o=listeOffre.get(i);
				o.setStatutOffre(6);
				metier.updateOffre(o);
				Message m=new Message("Offre archived", ((Employe)metierClient.getUtilisateur(34)), o.getExpediteur(), "your shipment "+o.getIdOffre()+" is archived",new Date());
				metierMessage.addMessage(m);
				
			}
			
		}
		return "g";
	}

	//envoyer un message au transporteur lorsqu'une déclaration a gagné
	public String DeclarationGagner()
	{
		
		List<Offre> listeOffre=metier.listeOffre(1,null,0) ;
		for(int i=0;i<listeOffre.size();i++)
		{
			
		//////////////
			 List<Declaration> ld=metierDec.getDeclarationGagnante(listeOffre.get(i));
			  //teser la dernière déclaration pour savoir si l'offre doit etre archivé ou pas
			  if(ld.size()!=0)
			  {
				  
				  if(ld.get(0).getPrice() <= listeOffre.get(i).getPrix_desire())
				  {
				 
				  Date DQMP=ld.get(0).getDateCreation();
				  
				  Date date = new Date();
				  
				  Calendar cal = Calendar.getInstance();
				  Calendar cal1 = Calendar.getInstance();
				    
				  cal1.setTime(date);
				  cal.setTime(DQMP);
				    
				  cal.add(Calendar.MINUTE, minutes);
				  
				    //régler le probleme de l'heur
				//  cal1.add(Calendar.HOUR, 1);
				  if(cal.getTime().compareTo(cal1.getTime())<=0)
				  {
					  
				
					//ajouter la declaration gagnante
					Offre o=ld.get(0).getOffre();
					o.setDecGanante(ld.get(0));
					metier.updateOffre(o);
					//envoyer à un transporteur
					Message mt=new Message("bid winner", ((Employe)metierClient.getUtilisateur(34)), ld.get(0).getTransporteur(),"the bid"+ld.get(0)+"is the winner accept the bid ",new Date()); 
					//anvoyer à l'expéditeur
					Message me=new Message("bid winner", ((Employe)metierClient.getUtilisateur(34)), ld.get(0).getOffre().getExpediteur(),"the bid"+ld.get(0)+"is the winner accept the bid ",new Date()); 
					
					metierMessage.addMessage(mt);
					metierMessage.addMessage(me);
					
					
				  }
				
				  }
				  
			  }
			
	    /////////////
			  
			
		}
		
		return "g";
	}
	
	
	//bider
	public String bider()
	{
		offre=metier.getOffre(IdOffre);
		Client carrier=((Client)metierClient.getUtilisateur(IdCarrier));
		Declaration dec=new Declaration(new Date(),price,carrier, metier.getOffre(IdOffre));
		dec.setStatut(1);
		metierDec.addDeclaration(dec);
	
		String a=carrier.getNom()+"  has placed a bid of "+price+" on your listing "+offre.getTitre();
	    //envoyer un message à l'expéditeur
		Message messageExp=new Message("New Bidding info",((Employe)metierClient.getUtilisateur(34)), offre.getExpediteur(), a,new Date());
		Message messageTra=new Message("New Bidding info", ((Employe)metierClient.getUtilisateur(34)), carrier,"This email confirms your bid on the shipment"+offre.getTitre(),new Date());
		metierMessage.addMessage(messageExp);
		metierMessage.addMessage(messageTra);
		return "ici";
		
	}
	
	//liste des transporteurs actifs
	public List<Client> listeTransporteur()
	{
		return metierClient.listeTransporteur();
	}
	
	//liste des messages d'un client
	public List<Message> listeMessage(Integer Id)
	{
		Client c=(Client) metierClient.getUtilisateur(Id);
		return c.getListeMessagesRecu();
	}
	
	
	//Espace Expéditeur
	//liste des offres
	public List<Offre> listeOffres()
	{
		//liste des offres actifs
				return metier.listeOffre(1,IdClient,0);
	}
	//liste des messages recu par un client
	public List<Message> listeMessages()
	{
		Client a=(Client)metierClient.getUtilisateur(IdClient);
		return a.getListeMessagesRecu();
	}
	
	//liste des déclarations
	public List<Declaration> listeDeclaration(Integer Type,String typeuser)
	{
		return metierDec.getAllDeclarationActivePrUser(IdClient,typeuser,Type);
	}
	
	
	public String EspaceExpediteur()
	{
		//liste des offres actifs
		listeOffre=metier.listeOffre(1,metier.getOffre(IdOffre).getExpediteur().getIdUtilisateur(),1);
		
		//récuperer l'expéditeur depuis l'offre
		Client Exp=metier.getOffre(IdOffre).getExpediteur();
		//liste des messages
		listeMessagesExpediteur=Exp.getListeMessagesRecu();
		
		//liste des déclarations
		listeDeclarations=metierDec.getAllDeclarationActivePrUser(Exp.getIdUtilisateur(),"Exp",1);
		//liste des déclarations acceptés
		listeDeclarationsAccept=metierDec.getAllDeclarationActivePrUser(Exp.getIdUtilisateur(),"Exp",2);
		//liste des déclarations refusée
		listeDeclarationsdecline=metierDec.getAllDeclarationActivePrUser(Exp.getIdUtilisateur(),"Exp",3);
		return "EspaceExpediteur.xhtml";
	}
	
	
	public String EspaceTransporteur()
	{
		//récuperer le transporteur en question
		Client Tra=(Client) metierClient.getUtilisateur(IdCarrier);
		//liste des messages
		listeMessagesTransporteur=Tra.getListeMessagesRecu();
	
		//liste des déclarations
		listeDeclarationsTr=metierDec.getAllDeclarationActivePrUser(Tra.getIdUtilisateur(),"Tra",1);
		//liste des déclarations acceptés
		listeDeclarationsAcceptTr=metierDec.getAllDeclarationActivePrUser(Tra.getIdUtilisateur(),"Tra",2);
		//liste des déclarations refusée
		listeDeclarationsdeclineTr=metierDec.getAllDeclarationActivePrUser(Tra.getIdUtilisateur(),"Tra",3);
		return "EspaceTransporteur.xhtml";
		
	}
	
	
	//accepter
	public String accepterDeclaration(Integer idDec,String type)
	{
	
		Declaration dec=metierDec.getDeclaration(idDec);
		Offre o=dec.getOffre();
		if(type.compareTo("Exp")==0)
		{
			System.out.println("Exp");
		//l'expéditeur a accepté la declaration
			
		
		
		//envoyer un message au transporteur
		String message="";
		if(dec.getStatutAccept().length()==2)
		{
			//modifier le statut de la declaration en accepted 2
			message="your quote is accepted"+idDec;
			dec.setStatut(2);
			metierDec.updateDeclaration(dec);
			//ajouter la déclaration gagante à l'offre
			o.setDecGanante(dec);
			metier.updateOffre(o);
			
		}
		else
		{
			System.out.println("#2Exp");
			dec.setStatutAccept(dec.getStatutAccept()+"E");
			metierDec.updateDeclaration(dec);
			System.out.println("Exp"+dec.getStatutAccept());
			message="the shipper accepted your bid please accepte the bid "+idDec;
		}
		Message m=new Message("bid accept", ((Employe)metierClient.getUtilisateur(34)),metierDec.getDeclaration(idDec).getTransporteur(),message, new Date());
		metierMessage.addMessage(m);
		
		}
		else
		{
			
			//envoyer un message au transporteur
			String message="";
			if(dec.getStatutAccept().length()==2)
			{
				System.out.println("2Tran");
				message="the quote the winner"+idDec;
				dec.setStatut(2);
				metierDec.updateDeclaration(dec);
				//ajouter la déclaration gagante à l'offre
				o.setDecGanante(dec);
				metier.updateOffre(o);
			}
			else
			{
				System.out.println("#2Tran");
				//l'expéditeur a accepté la declaration
				dec.setStatutAccept(dec.getStatutAccept()+"T");
				metierDec.updateDeclaration(dec);
				message="the carrier accepted your bid please accepte the bid "+idDec;
				
			}
			//envoyer un message au transporteur
			Message m=new Message("bid accept", ((Employe)metierClient.getUtilisateur(34)),metierClient.getUtilisateur(metierDec.getDeclaration(idDec).getOffre().getExpediteur().getIdUtilisateur()),message, new Date());
			metierMessage.addMessage(m);
			
		}
		
	return "a";
		//
	}
	
	//refuser une déclaration
	public String refuser(Integer idDec)
	{
	    Declaration dec=metierDec.getDeclaration(idDec);
	    Offre o=dec.getOffre();
	    dec.setStatut(3);
	    metierDec.updateDeclaration(dec);
	    String mssg="the bid "+idDec+" is declined";
	    //envoyer un message au transporteur
	    Message m=new Message("declined bid", ((Employe)metierClient.getUtilisateur(34)), dec.getTransporteur(), mssg, new Date());
	    //envoyer un message à l'expéditeur
	    Message m2=new Message("declined bid", ((Employe)metierClient.getUtilisateur(34)), dec.getOffre().getExpediteur(), mssg, new Date());
	    metierMessage.addMessage(m);
	    metierMessage.addMessage(m2);
	  //ajouter la déclaration gagante à l'offre
		o.setDecGanante(null);
		metier.updateOffre(o);
		return "here";
		
	}
	
	//espaceExpediteur
	public String espaceExpediteurs()
	{
		IdClient=metier.getOffre(IdOffre).getExpediteur().getIdUtilisateur();
		return "EspaceExpediteur.xhtml";
	}
	
	//espace Transporteur
		public String espaceTransporteurs()
		{
			IdClient=IdCarrier;
			return "EspaceTransporteur.xhtml";
		}

}
